package com.zhoug.plugin.android.constgenerator;

import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.RunResult;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import com.zhoug.plugin.android.constgenerator.beans.ConstField;
import com.zhoug.plugin.android.constgenerator.utils.PsiClassUtils;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public class ClassWriter {
    //项目
    private Project project;
    //目标类
    private PsiClass _psiClass;
    //目标类文件eg:xxx.java
    private PsiFile psiFile;
    //
    private List<ConstField> constFields;
    //PsiElement工厂
    private PsiElementFactory _psiElementFactory;

    public static boolean API26 = true;
    public static boolean prefixM = true;

    private PsiClassUtils mPsiClassUtils;


    public ClassWriter(Project project, PsiFile psiFile) {
        this(project, psiFile, null);
    }

    public ClassWriter(Project project, PsiFile psiFile, List<ConstField> constFields) {
        this.project = project;
        this.psiFile = psiFile;
        this.constFields = constFields;
        init();
    }

    private void init() {
        try {
            _psiElementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
        } catch (Exception e) {
            _psiElementFactory = PsiElementFactory.getInstance(project);
        }

        if (psiFile != null) {
            GlobalSearchScope scope = GlobalSearchScope.fileScope(psiFile);
            String name = psiFile.getName();
            System.out.println("psiFile=" + name);
            name = name.split("\\.")[0];
            _psiClass = PsiShortNamesCache.getInstance(project).getClassesByName(name, scope)[0];
            System.out.println("psiClass=" + _psiClass);
        }
    }




    /**
     * 生成代码
     */
    public void generateCode() {
        System.out.println("开始生成代码>>>>>>>>>>>>");
        //在类中写入全局变量和初始化方法
        RunResult execute = new WriteCommandAction(project, psiFile) {
            @Override
            protected void run(@NotNull Result result) throws Throwable {
                addFields();
            }
        }.execute();
    }

    /**
     * 向类中添加全局变量
     */
    private void addFields() {
        List<String> names = new ArrayList<>();
        List<String> values = new ArrayList<>();
        for (ConstField constField : constFields) {
            String fieldName = constField.getFieldName();
            String valueName = fieldName;
            String nameFieldName = fieldName + "_NAME";
            names.add(nameFieldName);
            values.add(valueName);
            createValueFields(valueName, constField.getValue());
            createNameFields(nameFieldName, constField.getName());
            createMethod_getName(names,values);
            createMethod_getValue(names,values);
        }

        createMethod_names(names);
        createMethod_values(values);

    }


    /**
     * 创建值 eg: public static final int TYPE_1=1;
     *
     * @param valueFieldName
     * @param value
     */
    private void createValueFields(String valueFieldName, int value) {
        PsiField psiField = _psiClass.findFieldByName(valueFieldName, false);
        //全局变量中是否已经创建了则删除
        if (psiField != null) {
            psiField.delete();
        }
        //没创建过
        String s = "public static final int" + " " +
                valueFieldName + " =  " +
                value + ";";
        System.out.println(s);
        PsiField fieldFromText = _psiElementFactory.createFieldFromText(s, _psiClass);
        _psiClass.add(fieldFromText);
    }

    /**
     * 创建name eg: public static final String TYPE_1_NAME="国有企业";
     *
     * @param nameFieldName
     * @param name
     */
    private void createNameFields(String nameFieldName, String name) {
        PsiField psiField = _psiClass.findFieldByName(nameFieldName, false);
        //全局变量中是否已经创建了则删除
        if (psiField != null) {
            psiField.delete();
        }
        //没创建过
        String s = "public static final String" + " " +
                nameFieldName + " =  "
                + "\"" +
                name +
                "\"" + ";";
        System.out.println(s);
        PsiField fieldFromText = _psiElementFactory.createFieldFromText(s, _psiClass);
        _psiClass.add(fieldFromText);
    }





    /**
     * 创建方法 public static List<String> names()
     *
     * @param names
     */
    public void createMethod_names(List<String> names) {
        PsiMethod[] namesMethod = _psiClass.findMethodsByName("names", false);
        PsiMethod method = namesMethod.length > 0 ? namesMethod[0] : null;
        if (method != null) {
            //已经创建了方法
            method.delete();
        }
        //创建方法
        StringBuilder methodBuffer = new StringBuilder();
        methodBuffer.append("public static List<String> names(){");
        methodBuffer.append("return Arrays.asList(");
        int len = names.size() - 1;
        for (int i = 0; i <= len; i++) {
            methodBuffer.append(names.get(i));
            if (i < len) {
                methodBuffer.append(",");
            }
        }
        methodBuffer.append(");");
        methodBuffer.append("}");
        String s = methodBuffer.toString();
        System.out.println(s);
        PsiMethod methodFromText = _psiElementFactory.createMethodFromText(s, _psiClass);
        _psiClass.add(methodFromText);

    }

    /**
     * 创建方法 public static List<Integer> values()
     *
     * @param values
     */
    public void createMethod_values(List<String> values) {
        PsiMethod[] namesMethod = _psiClass.findMethodsByName("values", false);
        PsiMethod method = namesMethod.length > 0 ? namesMethod[0] : null;
        if (method != null) {
            //已经创建了方法
            method.delete();
        }
        //创建方法
        StringBuilder methodBuffer = new StringBuilder();
        methodBuffer.append("public static List<Integer> values(){");
        methodBuffer.append("return Arrays.asList(");
        int len = values.size() - 1;
        for (int i = 0; i <= len; i++) {
            methodBuffer.append(values.get(i));
            if (i < len) {
                methodBuffer.append(",");
            }
        }
        methodBuffer.append(");");
        methodBuffer.append("}");
        String s = methodBuffer.toString();
        System.out.println(s);
        PsiMethod methodFromText = _psiElementFactory.createMethodFromText(s, _psiClass);
        _psiClass.add(methodFromText);

    }

    /**
     * 创建方法 public static String getName(int value)
     *
     * @param names
     * @param values
     */
    public void createMethod_getName(List<String> names, List<String> values) {
        PsiMethod[] namesMethod = _psiClass.findMethodsByName("getName", false);
        PsiMethod method = namesMethod.length > 0 ? namesMethod[0] : null;
        if (method != null) {
            //已经创建了方法
            method.delete();
        }
        //创建方法
        StringBuilder methodBuffer = new StringBuilder();
        methodBuffer.append("public static String getName(int value){");
        methodBuffer.append(" switch (value){");
        int len = values.size() - 1;
        for (int i = 0; i <= len; i++) {
            methodBuffer.append("case ")
                    .append(values.get(i))
                    .append(" :")
                    .append(" return ")
                    .append( names.get(i))
                    .append(" ;");
        }
        methodBuffer.append("}");//switch end
        methodBuffer.append("return null;");
        methodBuffer.append("}");
        String s = methodBuffer.toString();
        System.out.println(s);
        PsiMethod methodFromText = _psiElementFactory.createMethodFromText(s, _psiClass);
        _psiClass.add(methodFromText);

    }

    /**
     * 创建方法 public static int getValue(String name)
     *
     * @param names
     * @param values
     */
    public void createMethod_getValue(List<String> names, List<String> values) {
        PsiMethod[] namesMethod = _psiClass.findMethodsByName("getValue", false);
        PsiMethod method = namesMethod.length > 0 ? namesMethod[0] : null;
        if (method != null) {
            //已经创建了方法
            method.delete();
        }
        //创建方法
        StringBuilder methodBuffer = new StringBuilder();
        methodBuffer.append("public static int getValue(String name){");
        methodBuffer.append("if(name!=null){");
        int len = values.size() - 1;
        for (int i = 0; i <= len; i++) {
            methodBuffer.append("if(name.equals(")
                    .append(names.get(i))
                    .append("))")
                    .append(" return ")
                    .append( values.get(i))
                    .append(";");
        }
        methodBuffer.append("}");
        methodBuffer.append("return 0;");
        methodBuffer.append("}");
        String s = methodBuffer.toString();
        System.out.println(s);
        PsiMethod methodFromText = _psiElementFactory.createMethodFromText(s, _psiClass);
        _psiClass.add(methodFromText);

    }


}
